This page last changed on Aug 07, 2007 by aaime.

Geoserver 1.5.2 onwards has the ability to output good quality 256 color images. This tutorial introduces you to the palette concepts, the various image generation options, and offers a quality/resource comparison of them in different situations.

What are paletted images

Some image formtas, such as GIF or PNG, can use a palette, that is, a table of (usually) 256 colors to allow for better compression. Basically, instead of representing each pixel with its full color triplet, that is 24bits (plus eventual 8 more for transparency), they use a 8 bit index that represent the position inside the palette, and thus the color.
This allows for images that are 3-4 times smaller than the standard images, with the limitation that only 256 different colors can appear on the image itself.
Depending of the actual map, this may be a very stringent limitation, visibly degrading the image quality, or it may be that the output cannot be told from a full color image.

In the latter case, paletted images smaller footprint is usually a big gain in both performance and costs, because more data can be served with the same internet connection, and the clients will obtain responses faster.

Formats and antialiasing

Internet standards offer a variety of image formats, all having different strong and weak point. The three most common formats are:

  • JPEG, a lossy format with tunable compression. JPEG is best suited for imagery layers, where the pixel color varies continuously from one pixel to the next one, and allows for the best compressed outputs. On the contrary, it's not suited to most vector layers, because even slight compression generates visible artifacts on uniform color areas.
  • PNG, a non lossy format allowing for both full color and paletted. In full color images each pixel is encoded as a 24bits integer with full transparency information (so PNG images can be translucent), in paletted mode each pixel is an 8 bit index into a 256 color table (the palette). This format is best suited to vector layers, especially in the paletted version. The full color version is sometimes referred as PNG24, the paletted version as PNG8.
  • GIF, a non lossy format with a 256 colors palette, best suited for vector layers. Does not support translucency, but allows for fully transparent pixels.

So, as it turns out, paletted images can be used with profit on vector data sets, either using the PNG8 or GIF formats.
Antialiasing plays a role too. Let's take a road layer, where each road is depicted by a solid gray line, 2 pixels thick. One may thing this layer needs only 2 colors, the background one (eventually transparent) and gray. In fact, this is true only if no antialiasing is enabled. Antialiasing will smooth the borders of the line giving a softer, better looking shape, and it will do so by adding pixels with an intermediate color, thus increasing the number of colors that are needed to fully display the image.

The following zoom of an image shows antialiasing in action:

Options to enable paletted output

The easiest way to get a paletted image output is to ask for a 256 color output format, such as:

  • image/png8: PNG output, with a 256 color palette
  • image/gif: standard GIF output

These output formats, if no other parameters are provided, do compute the optimal palette on the fly. As you'll see, this is an expensive process (CPU bound), but as you'll see, depending on the speed of the network connecting the server and the client, the extra cost can be ignored (especially if the bottleneck can be found in the network instead of the server CPU).

Optimal palette computation is anyways a repetitive work that can be done up front: a user can compute the optimal palette once, and tell GeoServer to use it.
There are three ways to do so:

  • Use the internet safe palette, a standard palette built in into GeoServer, by appending palette=safe to the GetMap request.
    Of course, to get good results, the styling will have to be made using the colors in that palette.
  • Provide a palette by example. In this case, the user will generate an 256 color images using an external program (such as Photoshop), and then will save it into the $GEOSERVER_DATA_DIR/palettes directory. The sample file can be either in GIF or PNG format. If the file is named mypalette.gif or mypalette.png, the user will be able to refer it appending palette=mypalette to the GetMap request. GeoServer will load the palette from the file and use it.
  • Provide a palette file. The process is just as before, but this time only the palette, in .PAL format (Microsoft Palette Format, can be generated both by Paint Shop Pro and IrfanView), will be stored into $GEOSERVER_DATA_DIR/palettes.

An example with vector data

Enough theory, let's have a look at how to deal with paletted images in practice. We'll use the tiger-ny basemap to gather some numbers, and in particular the following map request:

http://localhost:8080/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=tiger-ny&BBOX=-74.022019,40.701196,-73.992366,40.720964&HEIGHT=400&WIDTH=600&FORMAT=image/png

and we'll change various parameters in order to play with formats and palettes. Here goes the sampler:

Parameters and comments Image
The standard PNG full color output.
Parameters: FORMAT=image/png
Size: 257 KB
Map generation time: 0.3s
The PNG8 output.
Parameters: {{FORMAT=image/png8}
Size: 60 KB
Map generation time: 0.6s
PNG + internet safe palette.
Parameters: FORMAT=image/png&palette=safe
Size: 56KB
Map generation time: 0.3s
PNG + custom palette.
Parameters: FORMAT=image/png&palette=nyp
Size: 56KB
Map generation time: 0.3s

The attachments include also the GIF outputs, whose size, appearance and generation time does not differ significantly from the PNG outputs.

As we can see, depending on the choice we have a variation on the image quality, size and generation time (which has been recorded using the FasterFox Firefox extension timer, with the browser sitting on the same box as the server). Using palette=xxx provides the best match in speed and size, thought using the built in internet safe palette altered the colors. Then again, the real gain can be seen only by assuming a certain connection speed between the server and the client, and adding the time required to move the image to the client. The following table provides some results:

Configuration GT (s) File size (kb) TT 256kbit/s TT 1MBit/s TT 4MBit/s TT 20MBit/s
tiger-ny-png 0,36 257 8,39 2,42 0,87 0,46
tyger-ny-png8 0,6 60 2,48 1,08 0,72 0,62
tiger-ny-png + safe palette 0,3 56 2,05 0,75 0,41 0,32
tiger-ny-png + custom palette 0,3 59 2,14 0,77 0,42 0,32

Legend:

  • GT: map generation time on the same box
  • TT <speed>: total time needed for a client to show the image, assuming an internet connection of the given speed. This time is a sum of of the image generation time and the transfer time, that is, GT + sizeInKbytes * 8/ speedInKbits.

As the table shows, the full color PNG image takes usually a lot more time than other formats, unless it's being served over a fast network (and even in this case, one should consider network congestion as well). The png8 output format proves to be a good choice if the connection is slow, whilst the extra work done in looking up an optimal palette always pays back in faster map delivery.

Generating the custom palette

The nyp.pal file has been generated using IrfanView, on Windows. The steps are simple:

  • open the png 24 bit version of the image
  • use Image/Decrease Color Depth and set 256 colors
  • use Image/Palette/Export to save the palette

An example with raster data

To give you an example when paletted images may not fit the bill, let's consider the sf:dem coverage from the sample data, and repeat the same operation as before.

Parameters and comments Image
The standard PNG full color output.
Parameters: FORMAT=image/png
Size: 117 KB
Map generation time: 0.2s
JPEG output
Parameters: FORMAT=image/jpeg
Size: 23KB
Map generation time: 0.12s
The PNG8 output.
Parameters: {{FORMAT=image/png8}
Size: 60 KB
Map generation time: 0.5s
PNG + custom palette (using the png8 output as the palette).
Parameters: FORMAT=image/png&palette=dem-png8
Size: 48KB
Map generation time: 0.15s
PNG + internet safe palette.
Parameters: FORMAT=image/png&palette=safe
Size: 17KB
Map generation time: 0.15s

As the sampler shows, the JPEG output has the same quality as the full color image, is generated faster and uses only 1/5 of its size. At the opposite, the version using the internet safe palette is fast and small, but the output is totally ruined. Everything considered, JPEG is the clear winner, sporting good quality, fast image generation and a size that's half of the best png output we can get.


antialiasing.gif (image/gif)
antialiasing.gif (image/gif)
tiger-ny-gif-safe-palette.gif (image/gif)
tiger-ny-png-safe-palette.png (image/png)
tiger-ny-gif.gif (image/gif)
tiger-ny-png8.png (image/png)
tiger-ny-png24.png (image/png)
tiger-ny-gif-custom-palette.gif (image/gif)
tiger-ny-png-custom-palette.png (image/png)
nyp.pal (application/octet-stream)
dem-jpeg.jpeg (image/jpeg)
dem-png-custom-palette.png (image/png)
dem-png-safe-palette.png (image/png)
dem-png8.png (image/png)
dem-png24.png (image/png)
Document generated by Confluence on Jan 16, 2008 23:27